home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / comm / term / term34Source.lha / termStringHook.c < prev    next >
C/C++ Source or Header  |  1993-07-16  |  9KB  |  429 lines

  1. /*
  2. **    termStringHook.c
  3. **
  4. **    Custom string gadget editing hook routines
  5. **
  6. **    Copyright © 1990-1993 by Olaf `Olsen' Barthel & MXM
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* Partial gadget support information. */
  13.  
  14. struct PartialGadgetSupportInfo
  15. {
  16.     STRPTR    Original,    /* Password string entry, original contents (for undo). */
  17.         Buffer;        /* Password string entry, current contents. */
  18. };
  19.  
  20.     /* CommandKey(struct Hook *Hook,struct SGWork *Work,ULONG *Msg):
  21.      *
  22.      *    This routine is called whenever input passes through
  23.      *    a `term' string gadget. It releases the currently
  24.      *    active string gadget as soon as the Right-Amiga-key is
  25.      *    pressed (user is about to select a menu item).
  26.      */
  27.  
  28. ULONG __saveds
  29. CommandKey(struct Hook *Hook,struct SGWork *Work,ULONG *Msg)
  30. {
  31.     if(*Msg == SGH_KEY)
  32.     {
  33.         if(Work -> EditOp == EO_ENTER)
  34.         {
  35.             if(!(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)))
  36.                 Work -> Actions |= SGA_NEXTACTIVE;
  37.             else
  38.                 Work -> Code = '\t';
  39.         }
  40.  
  41.         if(Work -> EditOp == EO_INSERTCHAR || Work -> EditOp == EO_REPLACECHAR)
  42.         {
  43.                 /* This looks like a built-in command. */
  44.  
  45.             if(Work -> IEvent -> ie_Qualifier & IEQUALIFIER_RCOMMAND)
  46.             {
  47.                     /* Amiga+C = Copy contents of string
  48.                      *           gadget to the clipboard.
  49.                      */
  50.  
  51.                 if(Work -> Code == 'c')
  52.                 {
  53.                     Work -> Actions &= ~SGA_USE;
  54.                     Work -> Actions |= SGA_BEEP;
  55.  
  56.                         /* Valid buffer contents? */
  57.  
  58.                     if(Work -> PrevBuffer[0])
  59.                     {
  60.                         struct MsgPort *ReplyPort;
  61.  
  62.                             /* Post a message... */
  63.  
  64.                         if(ReplyPort = CreateMsgPort())
  65.                         {
  66.                             struct Message ClipMessage;
  67.  
  68.                             ClipMessage . mn_Node . ln_Name    = Work -> PrevBuffer;
  69.                             ClipMessage . mn_ReplyPort    = ReplyPort;
  70.                             ClipMessage . mn_Length        = sizeof(struct Message);
  71.  
  72.                             PutMsg(ClipPort,&ClipMessage);
  73.  
  74.                             WaitPort(ReplyPort);
  75.  
  76.                             GetMsg(ReplyPort);
  77.  
  78.                             DeleteMsgPort(ReplyPort);
  79.  
  80.                             Work -> Actions &= ~SGA_BEEP;
  81.                         }
  82.                     }
  83.  
  84.                     return(1);
  85.                 }
  86.  
  87.                     /* Amiga+V = Insert current clipboard
  88.                      *           contents at cursor position.
  89.                      */
  90.  
  91.                 if(Work -> Code == 'v')
  92.                 {
  93.                     Work -> Actions &= ~SGA_USE;
  94.                     Work -> Actions |= SGA_BEEP;
  95.  
  96.                         /* Don't paste to integer gadgets
  97.                          * (it could confuse Intuition if
  98.                          *  the buffer contained non-numeric
  99.                          *  symbols...).
  100.                          */
  101.  
  102.                     if(!(Work -> Gadget -> Activation & GACT_LONGINT))
  103.                     {
  104.                         struct MsgPort *ReplyPort;
  105.  
  106.                             /* Post a message... */
  107.  
  108.                         if(ReplyPort = CreateMsgPort())
  109.                         {
  110.                             STATIC UBYTE    Buffer[2048];
  111.                             struct Message    ClipMessage;
  112.  
  113.                             Buffer[0] = 0;
  114.  
  115.                             ClipMessage . mn_Node . ln_Name    = Buffer;
  116.                             ClipMessage . mn_ReplyPort    = ReplyPort;
  117.                             ClipMessage . mn_Length        = sizeof(struct Message);
  118.  
  119.                             PutMsg(ClipPort,&ClipMessage);
  120.  
  121.                             WaitPort(ReplyPort);
  122.  
  123.                             GetMsg(ReplyPort);
  124.  
  125.                             DeleteMsgPort(ReplyPort);
  126.  
  127.                                 /* Anything in the buffer? */
  128.  
  129.                             if(Buffer[0])
  130.                             {
  131.                                 WORD Len = strlen(Buffer);
  132.  
  133.                                     /* Insert as many characters as we can. */
  134.  
  135.                                 while(Len > 0 && Work -> NumChars + Len > Work -> StringInfo -> MaxChars)
  136.                                     Len--;
  137.  
  138.                                     /* Any characters left? */
  139.  
  140.                                 if(Len > 0)
  141.                                 {
  142.                                     STATIC UBYTE OtherBuffer[2048];
  143.  
  144.                                         /* Provide null-termination. */
  145.  
  146.                                     Buffer[Len] = 0;
  147.  
  148.                                         /* Set up undo buffer correctly. */
  149.  
  150.                                     if(Work -> StringInfo -> UndoBuffer)
  151.                                         strcpy(Work -> StringInfo -> UndoBuffer,Work -> PrevBuffer);
  152.  
  153.                                     Work -> StringInfo -> UndoPos = --Work -> BufferPos;
  154.  
  155.                                         /* Save the characters before the cursor. */
  156.  
  157.                                     if(Work -> BufferPos)
  158.                                         CopyMem(Work -> PrevBuffer,OtherBuffer,Work -> BufferPos);
  159.  
  160.                                         /* Provide null-termination. */
  161.  
  162.                                     OtherBuffer[Work -> BufferPos] = 0;
  163.  
  164.                                         /* Append the clipboard data. */
  165.  
  166.                                     strcat(OtherBuffer,Buffer);
  167.  
  168.                                         /* Append the characters following the cursor. */
  169.  
  170.                                     strcat(OtherBuffer,&Work -> PrevBuffer[Work -> BufferPos]);
  171.  
  172.                                         /* = new work buffer. */
  173.  
  174.                                     strcpy(Work -> WorkBuffer,OtherBuffer);
  175.  
  176.                                         /* Fiddle with some cursor data. */
  177.  
  178.                                     Work -> BufferPos    += Len;
  179.                                     Work -> NumChars    += Len;
  180.  
  181.                                         /* And that's it... */
  182.  
  183.                                     Work -> Actions    |= SGA_USE;
  184.                                     Work -> EditOp     = EO_BIGCHANGE;
  185.  
  186.                                     Work -> Actions &= ~SGA_BEEP;
  187.                                 }
  188.                             }
  189.                             else
  190.                                 Work -> Actions &= ~SGA_BEEP;
  191.                         }
  192.                     }
  193.  
  194.                     return(1);
  195.                 }
  196.             }
  197.  
  198.                 /* Release the gadget in case a menu item is to be selected. */
  199.  
  200.             if((Work -> IEvent -> ie_Qualifier & AMIGARIGHT) && Work -> IEvent -> ie_Code < 96)
  201.             {
  202.                 if(!(Work -> IEvent -> ie_Qualifier & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT)) && (Work -> IEvent -> ie_Code == KEYCODE_X || Work -> IEvent -> ie_Code == KEYCODE_Q))
  203.                     return(1);
  204.                 else
  205.                 {
  206.                     Work -> Actions |= (SGA_END|SGA_REUSE);
  207.                     Work -> Actions &= ~(SGA_USE|SGA_BEEP);
  208.  
  209.                     CommandWindow = Work -> GadgetInfo -> gi_Window;
  210.                     CommandGadget = Work -> Gadget;
  211.                 }
  212.             }
  213.         }
  214.  
  215.             /* The user pressed the cursor-right key to
  216.              * move the cursor to the next word in the buffer.
  217.              */
  218.  
  219.         if(Work -> IEvent -> ie_Code == CURSORRIGHT && (Work -> IEvent -> ie_Qualifier & IEQUALIFIER_CONTROL))
  220.         {
  221.             if(Work -> BufferPos != Work -> NumChars)
  222.             {
  223.                 WORD i,Position = -1;
  224.  
  225.                 for(i = Work -> BufferPos ; i < Work -> NumChars ; i++)
  226.                 {
  227.                     if(Work -> WorkBuffer[i] == ' ')
  228.                     {
  229.                         for( ; i < Work -> NumChars ; i++)
  230.                         {
  231.                             if(Work -> WorkBuffer[i] != ' ')
  232.                             {
  233.                                 Position = i;
  234.                                 break;
  235.                             }
  236.                         }
  237.  
  238.                         break;
  239.                     }
  240.                 }
  241.  
  242.                 if(Position != -1)
  243.                     Work -> BufferPos = Position;
  244.                 else
  245.                     Work -> BufferPos = Work -> NumChars;
  246.  
  247.                 Work -> EditOp = EO_MOVECURSOR;
  248.             }
  249.         }
  250.  
  251.             /* The user pressed the cursor-right key to
  252.              * move the cursor to the previous word in the buffer.
  253.              */
  254.  
  255.         if(Work -> IEvent -> ie_Code == CURSORLEFT && (Work -> IEvent -> ie_Qualifier & IEQUALIFIER_CONTROL))
  256.         {
  257.             if(Work -> BufferPos)
  258.             {
  259.                 WORD i,Position = -1;
  260.  
  261.                 for(i = Work -> BufferPos ; i >= 0 ; i--)
  262.                 {
  263.                     if(Work -> WorkBuffer[i] != ' ')
  264.                     {
  265.                         Position = i;
  266.                         break;
  267.                     }
  268.                 }
  269.  
  270.                 if(Position == -1)
  271.                     Position = 0;
  272.  
  273.                 if(Position)
  274.                 {
  275.                     i = Position;
  276.  
  277.                     Position = -1;
  278.  
  279.                     for( ; i >= 0 ; i--)
  280.                     {
  281.                         if(Work -> WorkBuffer[i] == ' ')
  282.                         {
  283.                             Position = i + 1;
  284.                             break;
  285.                         }
  286.                     }
  287.                 }
  288.  
  289.                 if(Position != -1)
  290.                     Work -> BufferPos = Position;
  291.                 else
  292.                     Work -> BufferPos = 0;
  293.  
  294.                 Work -> EditOp = EO_MOVECURSOR;
  295.             }
  296.         }
  297.  
  298.         return(1);
  299.     }
  300.     else
  301.     {
  302.         if(*Msg == SGH_CLICK)
  303.             return(1);
  304.         else
  305.             return(0);
  306.     }
  307. }
  308.  
  309.     /* PasswordKey(struct Hook *Hook,struct SGWork *Work,ULONG *Msg):
  310.      *
  311.      *    Editing code for a password-entry string gadget. Credits for
  312.      *    the original implementation go to Hans-Joachim Widmaier.
  313.      */
  314.  
  315. ULONG __saveds
  316. PasswordKey(struct Hook *Hook,struct SGWork *Work,ULONG *Msg)
  317. {
  318.     struct PartialGadgetSupportInfo    *Info = (struct PartialGadgetSupportInfo *)Work -> Gadget -> UserData;
  319.     LONG                 Len;
  320.  
  321.     switch(*Msg)
  322.     {
  323.             /* Some key was pressed. */
  324.  
  325.         case SGH_KEY:
  326.  
  327.             switch(Work -> EditOp)
  328.             {
  329.                     /* Entered another character. */
  330.  
  331.                 case EO_INSERTCHAR:
  332.  
  333.                     Info -> Buffer[Work -> BufferPos - 1]        = Work -> Code;
  334.                     Info -> Buffer[Work -> NumChars]        = 0;
  335.  
  336.                     Work -> Code = '*';
  337.                     Work -> WorkBuffer[Work -> BufferPos - 1]    = '*';
  338.  
  339.                     break;
  340.  
  341.                     /* Undo changes. */
  342.  
  343.                 case EO_RESET:
  344.  
  345.                     Len = strlen(Info -> Original);
  346.  
  347.                     strcpy(Info -> Buffer,Info -> Original);
  348.  
  349.                     memset(Work -> WorkBuffer,'*',Len);
  350.  
  351.                     Work -> WorkBuffer[Len] = 0;
  352.  
  353.                     Work -> NumChars    = Len;
  354.                     Work -> BufferPos    = Len;
  355.                     Work -> EditOp         = EO_BIGCHANGE;
  356.  
  357.                     break;
  358.  
  359.                     /* Clear the gadget. */
  360.  
  361.                 case EO_CLEAR:
  362.  
  363.                     Work -> WorkBuffer[0]    = 0;
  364.                     Work -> NumChars    = 0;
  365.                     Work -> BufferPos    = 0;
  366.                     Work -> EditOp         = EO_BIGCHANGE;
  367.  
  368.                     Info -> Buffer[0]    = 0;
  369.  
  370.                     break;
  371.  
  372.                     /* Deleted the last character. */
  373.  
  374.                 case EO_DELBACKWARD:
  375.  
  376.                     Info -> Buffer[Work -> NumChars] = 0;
  377.                     break;
  378.  
  379.                     /* Default. */
  380.  
  381.                 case EO_NOOP:
  382.  
  383.                     break;
  384.  
  385.                     /* Terminate input. */
  386.  
  387.                 case EO_ENTER:
  388.  
  389.                     strcpy(Info -> Original,Info -> Buffer);
  390.                     break;
  391.  
  392.                     /* Don't move the cursor or try to
  393.                      * delete from the middle of the string.
  394.                      */
  395.  
  396.                 case EO_MOVECURSOR:
  397.                 case EO_DELFORWARD:
  398.  
  399.                     Work -> Actions &= ~SGA_USE;
  400.                     break;
  401.  
  402.                     /* Reject the rest. */
  403.  
  404.                 default:
  405.  
  406.                     Work -> Actions &= ~SGA_USE;
  407.                     Work -> Actions    |= SGA_BEEP;
  408.                     break;
  409.             }
  410.  
  411.             return(1);
  412.  
  413.             /* Clicking inside the box sets up the defaults. */
  414.  
  415.         case SGH_CLICK:
  416.  
  417.             Work -> BufferPos    = Work -> NumChars;
  418.             Work -> EditOp         = EO_BIGCHANGE;
  419.  
  420.             return(1);
  421.  
  422.             /* Reject the rest. */
  423.  
  424.         default:
  425.  
  426.             return(0);
  427.     }
  428. }
  429.